_____
                              _____  ___  /_______
                              __  / / /  __/  ___/
                              _  /_/ // /_ / /__
                              _\__, / \__/ \___/
                              /____/ytc98.cjb.net



Target Info
~"~"~"~"~"~

Name	   : Aareus IconCommander
URL	   : http://www.telusplanet.net/public/brbi/aareus/software/
Protection : Serial protection, crippled in unregistered version.



Introduction
~"~"~"~"~"~"

Hi there!

At first looks, I thought that this program is going to be a tough one,
since the buttons, windows and other stuffs doesn't look normal to me.
But, after disassembling it, I realized that it uses custom controls, 
written in VC++ (this is what IDA gave me). From their site, you can
obtain the source codes for writing custom controls in win32asm.

Okay, tutorial time ;).

Tools Needed
~"~"~"~"~"~"

Softice v3.x
IDA Pro v3.x
Asm compiler (for writing the keygen - optional)

The Essay
~"~"~"~"~

First of all, this program breaks on hmemcpy, so using it and tracing   
through, you will land yourself right after a call to SendMessageA at   
.text:1000679Fh. Notice that there's two more SendMessageA calls, so,      
simple deduction will tell you that these are the functions to get your
text from the registration dialog.

After the third SendMessageA call, it takes the first letter of your name
and compares it with zero, followed by a conditional jump, jz. This routine
checks if you entered anything into the 'Name' edit box, jumping to 'bad
serial' if you didn't put in any. Obviously, it only does the check to your
name, which means the 'Company' edit box can be left empty.

Next, you see it pushing the offsets of your name, company and password.
Then followed by a call to 1000B9F0h. Hmm...fishy. Lets take a look inside
this call.

Well, you find three calls to GlobalAlloc, then you find out that the
details you entered are being copied around. If you use IDA and look at
this section, you'll see call _memcpy. Isn't IDA just simply amazing? ;)

After all this copying around, you see another call, which is followed by
three calls to GlobalFree. Yup, this call must be the password generating
routine ;). So, what are we waiting for??

Step into the call, and whoa! Lots and lots of codes! Don't worry, just
keep tracing =). Lets see, a call to GlobalAlloc, then a RegOpenQueryExA,
two RegQueryValueExA and three lstrcpyA. Hmm..then you see your details
are being manipulated around. Here's a short snippet.


_text_1000BC32:
mov	esi, [ebp+var_38]     ;	put location of	password in esi
_text_1000BC35:
mov	al, [esi]	      ;	put first letter of password in	al
cmp	al, 0		      ;	cmp with 0
jz     _text_1000BC49         ; jump if 0, meaning password has ended
sub	al, 14h		      ;	subtract 14h from your password
mov	[esi], al	      ;	replace	letter with the	new value
inc	esi		      ;	increase pointer of password
jmp	_text_1000BC35        ; loop
_text_1000BC49:
mov	eax, [ebp+var_38]     ; put location of password in eax
push	eax		      ; push location of password
call	_atoi	              ; converts decimal string to hex in eax


OK, looks simple enough. Subtracts every character of your password with
14h, then convert it to hex. Meaning, your converted password MUST be
a decimal string (because of the call to _atoi). So, what about your 
UNCONVERTED password? It would be decimal number + 14h. So, lets find 
out the range of alphabets which is valid for use as password. The 
hex value for the smallest digit value, 0 (zero) is 30h, so, 30h+14h=68h, 
which is D. The hex value for the biggest digit value, 9 (nine) is 39h, 
so 39h+14h=77h, which is M. So our password consists of letters ranging 
from D to M.

OK, lets continue with the routine.


call	_atoi		      ;	convert	decimal	string to hex in eax
add	esp, 4		      ;	move stack pointer
mov	[ebp+var_20], eax     ;	saves converted	password
mov	eax, [ebp+var_14]     ;	takes location of name
mov	[ebp+var_1C], eax     ;	saves it
mov	eax, [ebp+var_C]      ;	takes location of company
mov	[ebp+var_30], eax     ;	saves it
mov	eax, [ebp+var_8]      ;	takes location of string "DefaultIcon"
mov	[ebp+var_4], eax      ;	saves it
mov	eax, [ebp+var_20]     ;	moves eax with converted password
rol	eax, 3		      ;	rotate left 3 bits
mov	edi, [ebp+var_4]      ;	takes location of string "DefaultIcon"
mov	edx, [edi]	      ;	move hex values	to edx
xor	eax, edx	      ;	xor it with the	rol-ed converted password
ror	eax, 7		      ;	rotate right the result	7 bits
mov	esi, [ebp+var_30]     ;	takes location of company
mov	edx, [esi]	      ;	moves hex values to edx
ror	edx, 2		      ;	rotate right it	2 bits
xor	eax, edx	      ;	xor it with the	result from previous calculation on password
mov	edi, [ebp+var_1C]     ;	takes location of your name
cmp	eax, [edi]	      ;	compare	the calculated result with hex values of name
jz	_text_1000BC95        ; jump to 'good_guy' if equal


If you don't know what ror, rol and xor are for, you better check with
your asm manual. I'm not going to explain such matters here ;).
Anyway, back to our code. Here's a summary of what it is doing.

1. Subtract 14h from each letter of your password to get decimal string.
2. Convert the decimal string to a hex value at eax.
3. ROL the hex value of your converted password 3 bits.
4. XOR it with hex values of the first 4 bytes in the string "DefaultIcon".
5. ROR the result 7 bits.
6. Takes the first 4 bytes of your company and ROR it 2 bits.
7. The result is XORed with result from step 5.
8. Final result is compared with the first 4 letters of your name.

Hmm...looks like there's some reversing to do ;). Beginning this part, I
would like to express my thanks to josephCo of MexElite for helping me
with this part.

Ok, so lets start thinking. The opposite of ROL is ROR, and vice versa.
The opposite of XOR is also XOR. Now, start working the calculation routine
the other way round.

1. Result in step 8 is your name, which is calculated from the XORed values
   of results from step 5 and step 6. The result of step 6 is a constant
   and doesn't need any reversing. By XORing our name with result of step 6
   will give us result for step 5.
2. For the constant, it's RORing the first 4 bytes of your company 2 bits.
3. ROLing 7 bits the result of step 5 will give us result for step 4.
4. XORing it with hex values from first 4 bytes of string "DefaultIcon" will
   give us result for step 3.
5. RORing this result 3 bits will give us our hex value of our converted 
   password.
6. Converting this hex value to string and adding 14h to each hex value
   will give us our valid serial.

Final Notes
~"~"~"~"~"~

Once again, I would really want to express my thanks to josephCo for
guiding and helping me in reversing this calculation routine. josephCo,
you're the best! ;)

Well, that's all for now. ytc_, signing off...


Author of Aareus Icon Commander, Arel Clayton, for allowing me to put up
this tutorial here. (I really appreciate this, thank you very very much).
Group greets : Phrozen Crew, MiB, MASSiVE, DEViOUS, ECG, PCG, HERITAGE, 
	       tNO, RAiD, WWC, MexElite
Personal greets : Iczelion, Kwai_Lo, Cr-S, hutch-, virogen, hayras,
		  JosephCo, Flu[X], Fresh--, blorght, immoral, Sleepers, 
		  Pr0phecy, Neural_N, KingGatso, ufk, _masta_, C4ffeine, 
		  Icecream, WKT_White, Sixx, +Malattia, +Cruehead, 
		  Icedragon, The+Q, HarvestR, BuLLeT, +gthorne (long 
		  time no see ;)), Ghiribizzo, Plushmm, Cali', _Hak_, 
		  zoltan, [Xorolc], [aLC], raza, Ousir, infamous, Mem_Lost,
		  Quantico, night_mastah, [Kiyone], Mister Fanatic, MisterE,
		  Iceman, and not to forget to those who shed light on 
		  me about cracking/reverse engineering (+ORC, Fravia+, 
		  Sandman, Mammon)
Channel greets : #cracking4newbies, #cracking, #win32asm, #cracking_forum

(If I miss anyone out or you don't like the order of my greets, please forgive me)

ytc_